/**
 * Filename: LoopMonthSwitchView.java
 * @author  Firefly
 * @contact postfirefly@163.com
 * @time    2016/5/17 11:49
 */
package com.github.postsanf.yinian.view;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.facebook.drawee.view.SimpleDraweeView;
import com.github.postsanf.yinian.R;
import com.github.postsanf.yinian.constants.CommonConstants;
import com.github.postsanf.yinian.utils.ImageOptHelper;
import com.github.postsanf.yinian.utils.YNUrlHelper;


@SuppressLint("NewApi")
public class LoopMonthSwitchView extends RelativeLayout{
	private Context mContext;						// 上下文
	private GestureDetector mGestureDetector; 		// 手势操作
	private float angle;							// 旋转的角度
	private List<View> views = new ArrayList<View>(); 	// 子View列表
	private int size  =  12; 						// 子控件个数
	private OnItemClickListener mItemClickListener;
	private OnItemSelcetListener mItemSelcetListener;
	private OnCenterClickListener mCenterClickListener;
	private OnLoopViewTouchListener mLoopViewTouchListener;
	private boolean isCanCilckListener = false;  	// 是否可以点击
	private int selectPosition; 					// 当前选中的Ttem位置
	private float last_angle; 						// 最后的角度，用来记录上一次取消touch之后的角度
	private final static int LoopR = 200;
	private float r =  LoopR;
	private float multiple = .9f; 					// 倍数，view之间的比例
	private float distance = multiple * r;  		// 子View之间的距离
	private boolean touching = false;				// 判断是否手指在touch
	private float distancX ;						// 在x轴上边移动的距离
	private float limitX = 30; 						// 滑动的阈值，用来判断能不能点击
	
	private ValueAnimator restAnimator = null;		// 复位动画
	private ValueAnimator roAnimator = null;		// 旋转动画
	private boolean isAuto = false;
	private boolean isLeftToRightScroll = true; 	// 默认自动滚动是否是从右往左
	private View	mCenterView;					// 中心位置View

	private SimpleDraweeView iv3;
	private SimpleDraweeView iv2;
	private SimpleDraweeView iv1;

	private AutoScrollHandler mHandler = new AutoScrollHandler(){
		void scroll() {
			if (size != 0) { // 判断自动滑动从哪边开始
				int perAngle = 0;
				if (isLeftToRightScroll) {
					perAngle = 360 /size;
				}else {
					perAngle = -360/size;
				}
				if (angle == 360) {
					angle = 0f;
				}
				AnimRotationTo(angle + perAngle, null);
			}
		};
	};

	public LoopMonthSwitchView(Context context, AttributeSet attrs,int defStyle){
		super(context, attrs, defStyle);
		init(context);
	}

	public LoopMonthSwitchView(Context context, AttributeSet attrs){
		super(context, attrs);
		init(context);
	}

	public LoopMonthSwitchView(Context context){
		super(context);
		init(context);
	}

	public void init(Context context){
		this.mContext = context;
		mGestureDetector = new GestureDetector(mContext, getGestureController()); // 创建手势对象

		// 初始化中心球体View
		View centerView = LayoutInflater.from(mContext).inflate(R.layout.globeview, null);
		addView(centerView);
		// 初始化月份View
		for(int i=1;i<13;i++){
			View view = LayoutInflater.from(mContext).inflate(R.layout.loopview_item_view0, null);
			((TextView)view.findViewById(R.id.tv_loopView)).setText(i+"");
			addView(view);
		}
		iv3 = (SimpleDraweeView) centerView.findViewById(R.id.iv_globe_3);
		iv2 = (SimpleDraweeView) centerView.findViewById(R.id.iv_globe_2);
		iv1 = (SimpleDraweeView) centerView.findViewById(R.id.iv_globe_1);

		// 初始化数据View半径
		DisplayMetrics metrics = new DisplayMetrics();
		WindowManager manager = (WindowManager) mContext.getSystemService(Service.WINDOW_SERVICE);
		manager.getDefaultDisplay().getMetrics(metrics);
		setR(metrics.widthPixels * 7/15);
		setAuto(false);
		setScrollInterval(5000);
		setLeftScroll(false);
	}

	private GestureDetector.SimpleOnGestureListener getGestureController(){
		return new GestureDetector.SimpleOnGestureListener(){
			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2,
					float distanceX, float distanceY) {
				// 计算滑动的角度
				angle += distanceX/views.size();
				initView();
				//tan(60°),手势与垂直方向大于30°,相应子View的onScroll,父控件的onScroll则不会响应
				if (1.732*Math.abs(distanceX) >= Math.abs(distanceY)){
					// 通知父控件不要拦截，事件我自行处理
					return true;
				} else {
					// 通知父控件拦截，响应父控件的onScroll
					getParent().requestDisallowInterceptTouchEvent(false);
					return false;
				}
			}
		};
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		// 进行控件界面的初始化
		initView();
		if (isAuto) {
			mHandler.sendEmptyMessageDelayed(AutoScrollHandler.messageId, mHandler.scroll_interval);
		}
	}

	private void initView() {
		int width = getWidth();
		r = width*7/15;
		for (int i = 0; i < views.size(); i++) {
			float x0 = (float)Math.sin(Math.toRadians(angle + 180 - i * 360 / size)) * r;
			float y0 = (float)(Math.cos(Math.toRadians(angle + 180 - i * 360 / size)) * 0.6 * r);
			float  scale0 = (distance - y0) / (distance + r);
			// 隐藏掉中间View遮挡的部分
			if(scale0 < 0.28 ){
				views.get(i).setScaleX(0);
				views.get(i).setScaleY(0);
			}else{
				views.get(i).setScaleX(scale0);
				views.get(i).setScaleY(scale0);
			}
			views.get(i).setX(width / 2 + x0 - views.get(i).getWidth() / 2);
			views.get(i).setY(getHeight()/2 - r/3 - y0/2);
		}

		// 设置中心View位置
		if(mCenterView!=null){
			ViewGroup.LayoutParams  mm = mCenterView.getLayoutParams();
			mm.width = width*7/10;
			mm.height = width*7/10;
			mCenterView.setLayoutParams(mm);
			mCenterView.setX(width / 2 - mCenterView.getWidth() / 2);
			mCenterView.setY(width / 2 - mCenterView.getWidth() / 2 + r/2);
		}

		List<View> arr = new ArrayList<View>();
		for (int i = 0; i < views.size(); i++){
			arr.add(views.get(i));
			views.get(i).setTag(i);
		}
		sortList(arr);
		// 刷新界面，重新排布
		postInvalidate();
	}

	@SuppressWarnings("unchecked")
	private <T> void sortList(List<View> arr) {
		@SuppressWarnings("rawtypes")
		Comparator comparator = new SortComparator();
		T[] array = arr.toArray((T[]) new Object[arr.size()]);

		Arrays.sort(array, comparator);
		int i = 0;
		ListIterator<T> it = (ListIterator<T>) arr.listIterator();
	        while (it.hasNext()) {
	            it.next();
	            it.set(array[i++]);
	        }
		for (int j = 0; j < arr.size(); j++) {
			arr.get(j).bringToFront();
		}
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		//对容器中的子view放置位置
		if (changed) {
			checkChildView();
			if (mItemSelcetListener != null) {
				isCanCilckListener = true;
				mItemSelcetListener.onSelect(selectPosition);
			}
			Ranimation();				//子view初始化动画
		}
	}
	public void Ranimation(){
		Ranimation(1f, r);
	}
	public void Ranimation(boolean fromZeroToR){
		if (fromZeroToR) {
			Ranimation(1f, LoopR);
		}else {
			Ranimation(LoopR, 1f);
		}
	}
	public void Ranimation(float from, float to) {
		roAnimator = ValueAnimator.ofFloat(from,to);
		roAnimator.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				r = (Float)animation.getAnimatedValue();
				initView();
			}
		});
		
		roAnimator.setInterpolator(new DecelerateInterpolator());
		roAnimator.setDuration(2000);
		roAnimator.start();
	}

	public View getViewByPos(int position){
		position = position< 0 ? size + position : position;
		return views.get(position);
	}

	//　获取子view并添加点击事件
	public void checkChildView(){
		for (int i = 0; i < views.size(); i++) {//先清空views里边可能存在的view防止重复
			views.remove(i);
		}
		final int count = getChildCount();//获取子View的个数
		size = count-1;

		for (int i = 0 ,pos = 0; i < count; i++,pos++) {
			View view = getChildAt(i); //获取指定的子view
			final int position = pos;
			// 判断是否是中心圆
			if (view.getId() == R.id.globe_rootview){
				pos--;
				mCenterView = view;
				mCenterView.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						if(isCanCilckListener && mCenterClickListener !=null){
							mCenterClickListener.onCenterClick();
						}
					}
				});
			}else{
				views.add(view);
				view.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						//对子view添加点击事件
						if (position != calculateItem()){
							setSelectItem(position);
						}else {
							if (isCanCilckListener && mItemClickListener != null) {
								mItemClickListener.onItemClick(position, views.get(position));
							}
						}
					}
				});
			}
		}
	}

	public void showCenterView(String urls){
		String rl = YNUrlHelper.getTimeCircleUrl(mContext, CommonConstants.defualt_iv2_url);
		if(urls==null || urls.length()==0){
			doDefault(rl);
		}else{
			String [] path = urls.split(",");
			String [] url =new String[3];
			switch(path.length){
				case 1:
					url[0]  = YNUrlHelper.getTimeCircleUrl(mContext, path[0]);
					url[1]  = rl;
					url[2]  = rl;
					break;
				case 2:
					url[0]  = YNUrlHelper.getTimeCircleUrl(mContext, path[0]);
					url[1]  = YNUrlHelper.getTimeCircleUrl(mContext, path[1]);
					url[2]  = rl;
					break;
				default:
					url[0]  = YNUrlHelper.getTimeCircleUrl(mContext, path[0]);
					url[1]  = YNUrlHelper.getTimeCircleUrl(mContext, path[1]);
					url[2]  = YNUrlHelper.getTimeCircleUrl(mContext, path[2]);
			}
			doNums(url);
		}
	}

	private void doDefault(String rl){
		ImageOptHelper.showFrescoTimeLine(Uri.parse(rl),iv3,mContext);
		ImageOptHelper.showFrescoTimeLine(Uri.parse(rl),iv2,mContext);
		ImageOptHelper.showFrescoTimeLine(Uri.parse(rl),iv1,mContext);
	}

	private void doNums(String [] urls){
		ImageOptHelper.showFrescoTimeLine(Uri.parse(urls[0]),iv3,mContext);
		ImageOptHelper.showFrescoTimeLine(Uri.parse(urls[1]),iv2,mContext);
		ImageOptHelper.showFrescoTimeLine(Uri.parse(urls[2]),iv1,mContext);
	}

	// 设置当前选中月份
	public void turn2month(int month){
		setAngle((month - 1) * (360 / size));
		doPosition((month - 1));
		System.out.println((month - 1) * (360 / size)+"========Angle================================"+angle);
	}

	private void doPosition(int selectItem){
		if (selectItem >= 0) {
			float corner = 0;
			if (getSelectPosition() == 0) {
				if (selectItem == views.size() - 1){
					corner = angle - (360 / size);
				}else{
					corner = angle + (360 / size);
				}
			}else if (getSelectPosition() == views.size() - 1){
				if (selectItem == 0) {
					corner = angle + (360 / size);
				}else {
					corner = angle - (360 /size);
				}
			}else{
				if (selectItem > getSelectPosition()){
					corner = angle +(360 /size);
				}else{
					corner = angle - (360 /size);
				}
			}

			float position = 0 ;
			float per = 360 /size;
			if (corner < 0) {
				per = -per;
			}
			float minValue = (int)(corner /per) * per;
			float maxValue = (int)(corner / per) * per + per;
			if (corner >= 0) {
				if (corner - last_angle > 0) {
					position = maxValue;
				}else {
					position = minValue;
				}
			}else {
				if (corner - last_angle < 0) {
					position = maxValue;
				}else {
					position = minValue;
				}
			}
			System.out.println(position+"========doPosition========="+maxValue+"======="+minValue);
			if (size > 0) {//旋转动画
				AnimRotationTo(position, null);
			}
		}
	}


	/**
	 * 设置所选中的item
	 * @param selectItem
	 */
	public void setSelectItem(int selectItem){
		if (selectItem >= 0) {
			float corner = 0;
			if (getSelectPosition() == 0) {
				if (selectItem == views.size() - 1){
					corner = angle - (360 / size);
				}else{
					corner = angle + (360 / size);
				}
			}else if (getSelectPosition() == views.size() - 1){
				if (selectItem == 0) {
					corner = angle + (360 / size);
				}else {
					corner = angle - (360 /size);
				}
			}else{
				if (selectItem > getSelectPosition()){
					corner = angle +(360 /size);
				}else{
					corner = angle - (360 /size);
				}
			}
			
			float position = 0 ;
			float per = 360 /size;
			if (corner < 0) {
				per = -per;
			}
			float minValue = (int)(corner /per) * per;
			float maxValue = (int)(corner / per) * per + per;
			if (corner >= 0) {
				if (corner - last_angle > 0) {
					position = maxValue;
				}else {
					position = minValue;
				}
			}else {
				if (corner - last_angle < 0) {
					position = maxValue;
				}else {
					position = minValue;
				}
			}
			if (size > 0) {//旋转动画
				AnimRotationTo(position, null);
			}
		}
	}
	public float getAngle() {
		return angle;
	}
	public void setAngle(float angle) {
		this.angle = angle;
	}
	public void setmItemClickListener(OnItemClickListener mItemClickListener) {
		this.mItemClickListener = mItemClickListener;
	}
	public void setmCenterClickListener(OnCenterClickListener mCenterClickListener){
		this.mCenterClickListener = mCenterClickListener;
	}
	public void setmItemSelcetListener(OnItemSelcetListener mItemSelcetListener) {
		this.mItemSelcetListener = mItemSelcetListener;
	}
	public void setmLoopViewTouchListener(
			OnLoopViewTouchListener mLoopViewTouchListener) {
		this.mLoopViewTouchListener = mLoopViewTouchListener;
	}

	public int calculateItem(){
		return (int)(angle / ( 360 / size)) % size;
	}

	public int getSelectPosition() {
		return selectPosition;
	}
	
	public float getR() {
		return r;
	}
	public LoopMonthSwitchView setR(float r) {
		this.r = r;
		distance = multiple * r;
		return this;
		
	}
	private  boolean onTouch(MotionEvent event){
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			last_angle = angle;
			touching = true;
		}
		boolean sc = mGestureDetector.onTouchEvent(event);
		if (sc) {
			this.getParent().requestDisallowInterceptTouchEvent(true);
		}
		if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
			touching = false;
			System.out.println("========================角度========================="+angle);
			restPosition();//重置
			return true;
		}
		return true;
	}
	
	private void restPosition() {
		if (size == 0) {
			return ;
		}
		
		float position = 0;
		float per = 360 /size;
		if (angle < 0) {
			per = -per;
		}
		
		float minValue = (int)(angle / per) * per;
		float maxValue = (int)(angle / per) * per ;
		if (angle > 0) {
			if (angle -last_angle > 0) {
				position = maxValue;
			}else {
				position = minValue;
			}
			
		}else {
			if (angle - last_angle > 0) {
				position  = angle == last_angle ? maxValue : minValue ;
			}else {
				position = angle == last_angle ? minValue : maxValue;
			}
		}
		
		AnimRotationTo(position,null);
	}

	private void AnimRotationTo(float position, final Runnable runnable) {
		if (angle == position) {//如果相同说明不需要旋转
			return;
		}
		restAnimator = ValueAnimator.ofFloat(angle,position);
		restAnimator.setInterpolator(new DecelerateInterpolator());//设置旋转减速插值器
		restAnimator.setDuration(300);
		restAnimator.addUpdateListener(new AnimatorUpdateListener() {
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				if (touching == false) {
					angle = (Float)animation.getAnimatedValue();
					initView();
				}
			}
		});
		
		restAnimator.addListener(new AnimatorListener() {
			@Override
			public void onAnimationStart(Animator animation) {
				
			}
			
			@Override
			public void onAnimationRepeat(Animator animation) {
				
			}
			
			@Override
			public void onAnimationEnd(Animator animation) {
				if (touching == false) {
					selectPosition = calculateItem();
				}
				if (mItemSelcetListener != null) {
					mItemSelcetListener.onSelect(selectPosition);
				}
			}
			
			@Override
			public void onAnimationCancel(Animator animation) {
				
			}
		});
		
		if (runnable != null) {
			restAnimator.addListener(new AnimatorListener() {
				
				@Override
				public void onAnimationStart(Animator animation) {
				}
				
				@Override
				public void onAnimationRepeat(Animator animation) {
				}
				
				@Override
				public void onAnimationEnd(Animator animation) {
					runnable.run();
				}
				
				@Override
				public void onAnimationCancel(Animator animation) {
				}
			});
		}
		restAnimator.start();
		
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (mLoopViewTouchListener != null) {
			mLoopViewTouchListener.onTouch(event);
		}
		isCanClickListener(event);
		return true;
	}
	
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		onTouch(ev);
		if (mLoopViewTouchListener != null) {
			mLoopViewTouchListener.onTouch(ev);
		}
		isCanClickListener(ev);
		return super.dispatchTouchEvent(ev);
	}
	
	public void isCanClickListener(MotionEvent event){
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			distancX = event.getX();
			if (isAuto) {
				mHandler.removeMessages(AutoScrollHandler.messageId);
			}
			break;
		case MotionEvent.ACTION_CANCEL:
		case MotionEvent.ACTION_UP:
			if (isAuto) {
				mHandler.sendEmptyMessageDelayed(AutoScrollHandler.messageId,  mHandler.scroll_interval);
			}
			if (event.getX() - distancX > limitX || distancX - event.getX() > limitX) {
				isCanCilckListener = false;
			}else{
				isCanCilckListener = true;
			}
			break;
		case MotionEvent.ACTION_MOVE:
			
			break;
		default:
			break;
		}
	}
	/**
	 * 自动滚动
	 */
	public void AutoScroll() {
		angle  = angle + (360/size);
		initView();
	}
	public boolean isAuto() {
		return isAuto;
	}
	public void setAuto(boolean isAuto) {
		this.isAuto = isAuto;
	}
	public boolean isLeftScroll() {
		return isLeftToRightScroll;
	}
	public void setLeftScroll(boolean isLeftToRightScroll) {
		this.isLeftToRightScroll = isLeftToRightScroll;
	}
	
	public void setScrollInterval(long time){
		if (mHandler != null) {
			mHandler.setScroll_interval(time);
		}
	}
}
